/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ar.edu.unicen.twitter.suggest.backend.datasources.twitterservices;

import ar.edu.unicen.twitter.suggest.backend.datasources.dao.ConfigDao;
import ar.edu.unicen.twitter.suggest.backend.dtos.OAuthApi;
import ar.edu.unicen.twitter.suggest.backend.dtos.TweetApi;
import ar.edu.unicen.twitter.suggest.backend.dtos.UsuarioBasico;
import ar.edu.unicen.twitter.suggest.interfaces.exceptions.UserProtectedException;
import ar.edu.unicen.twitter.suggest.interfaces.exceptions.RejectedException;
import ar.edu.unicen.twitter.suggest.interfaces.exceptions.TwitterException;
import ar.edu.unicen.twitter.suggest.interfaces.exceptions.UserNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import twitter4j.IDs;
import twitter4j.RateLimitStatus;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterFactory;
import twitter4j.TwitterResponse;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
import twitter4j.conf.ConfigurationBuilder;

/**
 *
 * @author usuario
 */
@Controller
@Scope("singleton")
public class TwitterClientImpl implements TwitterClient {

    @Autowired
    ConfigDao configDao;
    private static final Logger LOGGER = Logger.getLogger(TwitterClientImpl.class.getName());
    //variables de twitter
    private Twitter twitter;
    private String consumerKey = "egclpCPKBHzMHfGgSiqmQ";
    private String consumerSecret = "aL5liD9wYprEnPTwBPZcK6sq6mFrkNuGLfFFNo19p3I";
    private List<OAuthApi> accounts;
    private int cuentaActual = 0;
    private int contadorReintentar = 0;
    private static int STATUS_OK = 0;
    private static int STATUS_DISCONECTED = -1;
    private static int STATUS_BAD_REQUEST = 400;
    private static int STATUS_INVALID_TOKEN = 401;
    private static int STATUS_SUSPENDED = 403;
    private static int STATUS_LIMIT_REACHED_10 = 420;
    private static int STATUS_LIMIT_REACHED_11 = 429;
    private long PAGE_SIZE = 5000;
    private long PAGE_MAX_AMOUNT = 10;

    @PostConstruct
    public void init() {

        String[] consumer = "egclpCPKBHzMHfGgSiqmQ aL5liD9wYprEnPTwBPZcK6sq6mFrkNuGLfFFNo19p3I".split(" ");
        consumerKey = consumer[0];
        consumerSecret = consumer[1];


        accounts = configDao.getAuthAll();

//        accounts.add(new OAuthApi(271615453, "271615453-RiEzfpgDB7XntJGTXuvU9f51IlJzCJSI7fTRgOfs", "wDmbxHXtnnVFvD6Ij0VevHF34AJozHi0K8JTPHEL0"));
//        accounts.add(new OAuthApi(271619949, "271619949-Gq5DkeO3Uiqp4cqz9s1PPYi2tibtA0utrF6DLoPc", "ZqbijUoe3Y1ESUNvsSBVlQjZkFBi6SDzAKyy3cw1Zc"));
//        accounts.add(new OAuthApi(271624755, "271624755-A4Hc9qO3UWsFhQrLYuonGQdDma9xCdxAjv2iuxSU", "Bln8O0gQBCQnEhw3GhK8ptPzrBgwQ9oQAkKmLPFDNs"));
//        accounts.add(new OAuthApi(272630774, "272630774-bqauRlPvoYpGUateN8Xoc8uzBpj6rD4dFhMkjLhg", "4i2f5JCIUKCQoS5x7gNMAazPyRAvhbDFO0At4Uk"));
//        accounts.add(new OAuthApi(272634449, "272634449-ofOAGtMXtNv62DIYFQLBXIP3AzN7XNXXSVAdZTig", "6s3wCiBhza80ZT84vpfpMv1xrSkeX6zXgY9AWgKJXw"));
//        accounts.add(new OAuthApi(272634998, "272634998-tSs9MLM8ZRbFKI6tsHyVPc37kR5QgFM435yAp2Ue", "G3LVHR4YaNTbBB90FNboLG0psMRgt5fHb04kvojew"));
//        accounts.add(new OAuthApi(272630623, "272630623-vNDNKuoDAVO0hgXgnHB7acoJ2ji9gAJdD5fafWjU", "Zalg0jSbImzcSVsoc0W9lLdL6jmSvLSpinHXMRb4"));
//        accounts.add(new OAuthApi(272633738, "272633738-3VR735WWLt9meSTDyLLw3oK2przivsvkniBzDniQ", "dLvQ1UwM9CS0EEOydGHsMte6iH0eoM9pLfkS5gTNj4"));
//        accounts.add(new OAuthApi(272634322, "272634322-6b7dFosP7Fro61XWOynbpttygGCal0SkRMidSKfN", "k5ExIUIhMAsQ70e5BZCc0Bv3y6GyeaXea2fo6ZfoE"));
//        accounts.add(new OAuthApi(272634878, "272634878-bgOGOT0ZjkGQ9ljPVIQKTgLHktC8I567vYmQE1Qk", "k59FlvsbJ6IBSA7vCrR0jkmy34tl6eHhlNFUSEQm7fA"));
//        accounts.add(new OAuthApi(272635259, "272635259-nMshpo0mXqTkJeSffDGKoJvwvJLuUL8YaClxg9Xw", "nLy1fiD44yie5yCyk7f9XrSmGdnRt56T2Wa1mpqxAmI"));
//        accounts.add(new OAuthApi(272636161, "272636161-v0Xn1TsyhDC4219xKpQQrJT4K89MhAOxAyUg0BlK", "TCUh4wPYrTsw7ghTeIpgXOdES9ixmlMBo6P5CgLOXg"));
//        accounts.add(new OAuthApi(294731376, "294731376-za3VGntCLL5LYFwRZYYp4llQGgC0COzYc4KuE1AC", "3bNPbXHgjjg6wiqxa3Lp29ha2b16Rj8d5rgquwcww"));
//        accounts.add(new OAuthApi(294735292, "294735292-EDjcoWWdqaOJ9ZTTUVTOhpihl7NVGp3whA4kBw3n", "gU0cnACCd19KoapnX84eaYjcSPsEv0JX6wbDjCXLGSg"));
//        accounts.add(new OAuthApi(272630623, "272630623-vNDNKuoDAVO0hgXgnHB7acoJ2ji9gAJdD5fafWjU", "Zalg0jSbImzcSVsoc0W9lLdL6jmSvLSpinHXMRb4"));

        //configDao.update(accounts);
    }

    @Override
    public UsuarioBasico getUserData(long id) throws UserNotFoundException, UserProtectedException, RejectedException, TwitterException {
        boolean done = false;
        boolean isprotected = true;
        while (!done) {
            try {
                twitter4j.User user = null;
                //LOGGER.log(Level.INFO, "Obteniendo userData de {0}", id);
                user = getTwitter(null).showUser(id);
                UsuarioBasico result = new UsuarioBasico();
                result.setId(user.getId());
                result.setFollowersCount(user.getFollowersCount());
                result.setFriendsCount(user.getFriendsCount());
                result.setTweetsCount(user.getStatusesCount());
                result.setLang(user.getLang());
                result.setProtected(user.isProtected());
                result.setScreenName(user.getScreenName());
                result.setUrl(user.getURL());
                updateTwitter(user);
                //LOGGER.log(Level.INFO, "UserData obtenida con exito: {0}", id);
                return result;
            } catch (twitter4j.TwitterException ex) {
                if (ex.getStatusCode() == STATUS_BAD_REQUEST || ex.getStatusCode() == STATUS_LIMIT_REACHED_10 || ex.getStatusCode() == STATUS_LIMIT_REACHED_11) {
                    getTwitter(ex);
                } else if (ex.getStatusCode() == STATUS_INVALID_TOKEN) {
                    if (!isprotected) {
                        isprotected = true;
                        getTwitter(ex);
                    } else {
                        UsuarioBasico result = new UsuarioBasico();
                        result.setId(id);
                        result.setProtected(true);
                        return result;
                    }
                } else if (ex.getStatusCode() == STATUS_DISCONECTED) {
                    contadorReintentar = (contadorReintentar + 1) % 10;
                    if (contadorReintentar == 0) {
                        LOGGER.log(Level.WARNING, "REINTENTAR -1");
                    }
                } else if (ex.getStatusCode() == 503 || ex.getStatusCode() == 502) {
                    LOGGER.log(Level.WARNING, "REINTENTAR 503" + " [getFollows(" + id + ")]");
                } else if (ex.getStatusCode() == 500) {
                    LOGGER.log(Level.WARNING, "REINTENTAR 500" + " [getFollows(" + id + ")]");
                } else if (ex.getStatusCode() == 403) {
                    throw new RejectedException("userid:" + id);
                } else if (ex.getStatusCode() == 404) {
                    throw new UserNotFoundException("userid:" + id);
                } else {
                    throw new TwitterException("excepcion:" + ex);
                }
            }
        }
        return null;
    }

    @Override
    public UsuarioBasico getUserData(String screenName) throws UserNotFoundException, UserProtectedException, RejectedException, TwitterException {
        boolean done = false;
        boolean isprotected = false;
        while (!done) {
            try {
                twitter4j.User user = null;
                //LOGGER.log(Level.INFO, "Obteniendo userData de {0}", screenName);
                user = getTwitter(null).showUser(screenName);
                UsuarioBasico result = new UsuarioBasico();
                result.setId(user.getId());
                result.setFollowersCount(user.getFollowersCount());
                result.setFriendsCount(user.getFriendsCount());
                result.setLang(user.getLang());
                result.setProtected(user.isProtected());
                result.setScreenName(user.getScreenName());
                result.setUrl(user.getURL());
                result.setTweetsCount(user.getStatusesCount());
                updateTwitter(user);
                //LOGGER.log(Level.INFO, "UserData obtenida con exito: {0}", user);
                return result;
            } catch (twitter4j.TwitterException ex) {
                if (ex.getStatusCode() == STATUS_BAD_REQUEST || ex.getStatusCode() == STATUS_LIMIT_REACHED_10 || ex.getStatusCode() == STATUS_LIMIT_REACHED_11) {
                    getTwitter(ex);
                } else if (ex.getStatusCode() == STATUS_INVALID_TOKEN) {
                    if (!isprotected) {
                        isprotected = true;
                        getTwitter(ex);
                    } else {
                        UsuarioBasico result = new UsuarioBasico();
                        result.setScreenName(screenName);
                        result.setProtected(true);
                        return result;
                    }
                } else if (ex.getStatusCode() == STATUS_DISCONECTED) {
                    contadorReintentar = (contadorReintentar + 1) % 10;
                    if (contadorReintentar == 0) {
                        LOGGER.log(Level.WARNING, "REINTENTAR -1");
                    }
                } else if (ex.getStatusCode() == 503 || ex.getStatusCode() == 502) {
                    LOGGER.log(Level.WARNING, "REINTENTAR 503" + " [getFollows(" + screenName + ")]");
                } else if (ex.getStatusCode() == 500) {
                    LOGGER.log(Level.WARNING, "REINTENTAR 500" + " [getFollows(" + screenName + ")]");
                } else if (ex.getStatusCode() == 403) {
                    throw new RejectedException("username:" + screenName);
                } else if (ex.getStatusCode() == 404) {
                    throw new UserNotFoundException("username:" + screenName);
                } else {
                    throw new TwitterException("excepcion:" + ex);
                }
            }
        }
        return null;
    }

    @Override
    public List<TweetApi> getNewTweets(String screenName) throws UserNotFoundException, UserProtectedException, RejectedException, TwitterException {
        List<TweetApi> result = null;
        boolean done = false;
        while (!done) {
            try {
                //System.out.println("getNewTweets("+ID+")");
                result = new ArrayList<TweetApi>();
                List<Status> recentPublications = getTwitter(null).getUserTimeline(screenName); //Publicaciones recientes de usuario
                ListIterator<Status> lIterator = recentPublications.listIterator();
                while (lIterator.hasNext()) {
                    //Recorre la lista de Status del usuario
                    Status actual = lIterator.next();
                    TweetApi t = new TweetApi();
                    t.setCreatedAt(actual.getCreatedAt());
                    t.setText(actual.getText());
                    t.setTweetId(actual.getId());
                    result.add(t);
                }
                done = true;
            } catch (twitter4j.TwitterException ex) {
                if (ex.getStatusCode() == STATUS_BAD_REQUEST || ex.getStatusCode() == STATUS_LIMIT_REACHED_10 || ex.getStatusCode() == STATUS_LIMIT_REACHED_11) {
                    getTwitter(ex);
                } else if (ex.getStatusCode() == STATUS_INVALID_TOKEN) {
                    //throw new UserProtectedException("userid:" + screenName);
                    getTwitter(ex);
                } else if (ex.getStatusCode() == STATUS_DISCONECTED) {
                    contadorReintentar = (contadorReintentar + 1) % 10;
                    if (contadorReintentar == 0) {
                        LOGGER.log(Level.WARNING, "REINTENTAR -1");
                    }
                } else if (ex.getStatusCode() == 503 || ex.getStatusCode() == 502) {
                    LOGGER.log(Level.WARNING, "REINTENTAR 503" + " [getFollows(" + screenName + ")]");
                } else if (ex.getStatusCode() == 500) {
                    LOGGER.log(Level.WARNING, "REINTENTAR 500" + " [getFollows(" + screenName + ")]");
                } else if (ex.getStatusCode() == 403) {
                    throw new RejectedException("userid:" + screenName);
                } else if (ex.getStatusCode() == 404) {
                    throw new UserNotFoundException("userid:" + screenName);
                } else {
                    throw new TwitterException("excepcion:" + ex);
                }
            }
        }
        return result;
    }

    @Override
    public List<TweetApi> getAllTweets(String screenName, int page) throws UserNotFoundException, UserProtectedException, RejectedException, TwitterException {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public long[] getFollowers(String screenName, int maxCount) throws UserNotFoundException, UserProtectedException, RejectedException, TwitterException {
        boolean done = false;
        while (!done) {
            try {
                long[] result;
                if (maxCount == PAGE_SIZE) {
                    result = getTwitter(null).getFollowersIDs(screenName, -1).getIDs();
                } else {
                    result = new long[maxCount];
                    long[] page;
                    int offset = 0;
                    long cursor = -1;
                    int pageCount = 0;
                    int validCount = 0;
                    do {
                        IDs ids = getTwitter(null).getFollowersIDs(screenName, cursor);
                        page = ids.getIDs();
                        for (int r = 0; r < page.length && validCount < maxCount; r++) {
                            if (page[r] != 0) {
                                result[validCount] = page[r];
                                ++validCount;
                            }
                        }
                        updateTwitter(ids);
                        cursor = ids.getNextCursor();
                        pageCount++;
                    } while (validCount < maxCount && cursor != 0 && pageCount <= PAGE_MAX_AMOUNT);
                    if (validCount < maxCount) {
                        long[] packedResult = new long[validCount];
                        for (int r = 0; r < validCount; r++) {
                            packedResult[r] = result[r];
                        }
                        result = packedResult;
                    }
                }
                return result;
            } catch (twitter4j.TwitterException ex) {
                if (ex.getStatusCode() == STATUS_BAD_REQUEST || ex.getStatusCode() == STATUS_LIMIT_REACHED_10 || ex.getStatusCode() == STATUS_LIMIT_REACHED_11) {
                    getTwitter(ex);
                } else if (ex.getStatusCode() == STATUS_INVALID_TOKEN) {
                    // throw new UserProtectedException("user:" + screenName);
                    getTwitter(ex);
                } else if (ex.getStatusCode() == STATUS_DISCONECTED) {
                    contadorReintentar = (contadorReintentar + 1) % 10;
                    if (contadorReintentar == 0) {
                        LOGGER.log(Level.WARNING, "REINTENTAR -1");
                    }
                } else if (ex.getStatusCode() == 503 || ex.getStatusCode() == 502) {
                    LOGGER.log(Level.WARNING, "REINTENTAR 503" + " [getFollows(" + "user:" + screenName + ")]");
                } else if (ex.getStatusCode() == 500) {
                    LOGGER.log(Level.WARNING, "REINTENTAR 500" + " [getFollows(" + "user:" + screenName + ")]");
                } else if (ex.getStatusCode() == 403) {
                    throw new RejectedException("user:" + screenName);
                } else if (ex.getStatusCode() == 404) {
                    throw new UserNotFoundException("user:" + screenName);
                } else {
                    throw new TwitterException("excepcion:" + ex);
                }
            }
        }
        return null;
    }

    @Override
    public long[] getFollows(String screenName, int maxCount) throws UserNotFoundException, UserProtectedException, RejectedException, TwitterException {
        boolean done = false;
        while (!done) {
            try {
                long[] result;
                if (maxCount == PAGE_SIZE) {
                    result = getTwitter(null).getFriendsIDs(screenName, -1).getIDs();
                } else {
                    result = new long[maxCount];
                    long[] page;
                    int offset = 0;
                    long cursor = -1;
                    int pageCount = 0;
                    int validCount = 0;
                    do {
                        IDs ids = getTwitter(null).getFriendsIDs(screenName, cursor);
                        page = ids.getIDs();
                        for (int r = 0; r < page.length && validCount < maxCount; r++) {
                            if (page[r] != 0) {
                                result[validCount] = page[r];
                                ++validCount;
                            }
                        }
                        cursor = ids.getNextCursor();
                        updateTwitter(ids);
                        pageCount++;
                    } while (validCount < maxCount && cursor != 0 && pageCount <= PAGE_MAX_AMOUNT);
                    if (validCount < maxCount) {
                        long[] packedResult = new long[validCount];
                        for (int r = 0; r < validCount; r++) {
                            packedResult[r] = result[r];
                        }
                        result = packedResult;
                    }
                }

                return result;
            } catch (twitter4j.TwitterException ex) {
                if (ex.getStatusCode() == STATUS_BAD_REQUEST || ex.getStatusCode() == STATUS_LIMIT_REACHED_10 || ex.getStatusCode() == STATUS_LIMIT_REACHED_11) {
                    getTwitter(ex);
                } else if (ex.getStatusCode() == STATUS_INVALID_TOKEN) {
                    getTwitter(ex);
                } else if (ex.getStatusCode() == STATUS_DISCONECTED) {
                    contadorReintentar = (contadorReintentar + 1) % 10;
                    if (contadorReintentar == 0) {
                        LOGGER.log(Level.WARNING, "REINTENTAR -1");
                    }
                } else if (ex.getStatusCode() == 503 || ex.getStatusCode() == 502) {
                    LOGGER.log(Level.WARNING, "REINTENTAR 503" + " [getFollows(" + "user:" + screenName + ")]");
                } else if (ex.getStatusCode() == 500) {
                    LOGGER.log(Level.WARNING, "REINTENTAR 500" + " [getFollows(" + "user:" + screenName + ")]");
                } else if (ex.getStatusCode() == 403) {
                    throw new RejectedException("user:" + screenName);
                } else if (ex.getStatusCode() == 404) {
                    throw new UserNotFoundException("user:" + screenName);
                } else {
                    throw new TwitterException("excepcion:" + ex);
                }
            }
        }
        return null;
    }

    private Twitter getTwitter(String token, String tokenSecret) {
        ConfigurationBuilder cb = new ConfigurationBuilder();
        cb.setDebugEnabled(false)
                .setOAuthConsumerKey(consumerKey)
                .setOAuthConsumerSecret(consumerSecret)
                .setOAuthAccessToken(token)
                .setOAuthAccessTokenSecret(tokenSecret);
        TwitterFactory tf = new TwitterFactory(cb.build());
        Twitter twitter = tf.getInstance();
        AccessToken accessToken = new AccessToken(token, tokenSecret);
        twitter.setOAuthAccessToken(accessToken);
        return twitter;
    }

    public RateLimitStatus limit(String endpoint) throws twitter4j.TwitterException {
        String family = endpoint.split("/", 3)[1];
        RateLimitStatus status = twitter.getRateLimitStatus(family).get(endpoint);
        return status;
    }

    /**
     * devuelve una cuenta de twitter valida; una cuenta deja de ser valida si
     * ha alcanzado el maximo la cantidad de consultas CONSULTAS_MAX.
     *
     * @param newTwitter indica si debe forzarse el cambio de cuenta.
     * @return cuenta de twitter valida.
     */
    int cuentaInicial = 0;
    private Twitter getTwitter(twitter4j.TwitterException status) {

        if (status != null || twitter == null) {

            boolean retry = false;
            //do {
            boolean changeAccount = false;
            cuentaInicial = cuentaInicial % accounts.size();
            if (twitter == null) {
                changeAccount = true;
            } else {
                if (status != null) {
                    OAuthApi account = accounts.get(cuentaActual);
                    if (status.getStatusCode() == STATUS_INVALID_TOKEN) {
                        changeAccount = true;
                    } else if (status.getStatusCode() == STATUS_SUSPENDED) {
                        account.setSuspended(true);
                        configDao.update(account);
                        changeAccount = true;

                    } else if (status.getStatusCode() == STATUS_LIMIT_REACHED_10 || status.getStatusCode() == STATUS_LIMIT_REACHED_11) {
                        changeAccount = true;
                    } else if (status.getStatusCode() == STATUS_DISCONECTED) {
                        changeAccount = true;
                    }
                    if (account.getLimitStatus() != null) {
                        LOGGER.log(Level.INFO, "Cambio de cuenta ({0}/{1}) status = {2} detalle = {3} nueva cuenta:{4} esperar:{5} " + status.getErrorMessage(), new Object[]{account.getLimitStatus().getRemaining(), account.getLimitStatus().getLimit(), status.getStatusCode(), status.getErrorMessage(), accounts.get(cuentaActual).getScreenName(), account.getLimitStatus().getSecondsUntilReset()});
                    } else {
                        LOGGER.log(Level.INFO, "Cambio de cuenta ({0}/{1}) status = {2} detalle = {3} nueva cuenta:{4} " + status.getErrorMessage(), new Object[]{"?", "?", status.getStatusCode(), status.getErrorMessage(), accounts.get(cuentaActual).getScreenName()});
                    }
                } else {
                    LOGGER.log(Level.INFO, "Cambio de cuenta ({0}/{1}) status = {2} detalle = {3} nueva cuenta:{4}", new Object[]{"?", "?", status.getStatusCode(), status.getErrorMessage(), accounts.get(cuentaActual).getScreenName()});
                }
            }
            if (changeAccount) {

                if (accounts.get(cuentaActual).isSuspended()) {
                    LOGGER.log(Level.INFO, "Cuenta suspendida: {0}", accounts.get(cuentaActual).getScreenName());
                    //  accounts.remove(cuentaActual);
                    cuentaActual = (cuentaActual + 1) % accounts.size();
                } else {
                    cuentaActual = (cuentaActual + 1) % accounts.size();
                }
                OAuthApi account = accounts.get(cuentaActual);
                twitter = getTwitter(account.getToken(), account.getTokenSecret());

                if (!retry && account.getScreenName() == null) {
                    try {
                        account.setScreenName(twitter.verifyCredentials().getScreenName());
                        configDao.update(accounts.get(cuentaActual));
                    } catch (twitter4j.TwitterException ex) {
                        Logger.getLogger(TwitterClientImpl.class.getName()).log(Level.SEVERE, null, ex);
                        status = ex;
                        retry = true;
                        //accounts.remove(cuentaActual);
                        //cuentaActual = (cuentaActual) % accounts.size();
                    }
                }
                if (cuentaInicial == cuentaActual) {
                    try {
                        RateLimitStatus limitStatus = accounts.get(cuentaActual).getLimitStatus();
                        long waitTime;
                        if (limitStatus != null) {
                            waitTime = limitStatus.getResetTimeInSeconds() * 1000;
                        } else {
                            waitTime = 60 * 1000;
                        }
                        if (account.getLimitStatus() != null) {
                            waitTime = Math.max(waitTime, account.getLimitStatus().getSecondsUntilReset() * 1000);
                        }
                        LOGGER.log(Level.INFO, "No hay cuentas disponibles, esperando {0} segundos", waitTime / 1000);
                        Thread.sleep(waitTime);

                        retry = false;
                        account = accounts.get(cuentaActual);
                        twitter = getTwitter(account.getToken(), account.getTokenSecret());

                    } catch (InterruptedException ex) {
                        Logger.getLogger(TwitterClientImpl.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            } else {
                if (status != null) {
                    OAuthApi account = accounts.get(cuentaActual);
                    if(account.getLimitStatus()!=null)
                        LOGGER.log(Level.INFO, "Reuso de cuenta ({0}/{1}) status = {2} detalle = {3} nueva cuenta:{4}" + status.getErrorMessage(), new Object[]{account.getLimitStatus().getRemaining(), account.getLimitStatus().getLimit(), status.getStatusCode(), status.getErrorMessage(), accounts.get(cuentaActual).getScreenName()});
                } else {
                    RateLimitStatus limitStatus = accounts.get(cuentaActual).getLimitStatus();
                    if (limitStatus != null) {
                        LOGGER.log(Level.INFO, "Reuso de cuenta ({0}/{1}) status = {2} detalle = {3} nueva cuenta:{4}", new Object[]{limitStatus.getRemaining(), limitStatus.getLimit(), null, null, accounts.get(cuentaActual).getScreenName()});
                    } else {
                        LOGGER.log(Level.INFO, "Reuso cuenta, sin informacion estado");
                    }
                }
                //cuentaInicial =cuentaActual;
            }
            // } while (retry);
        } else {
            if (status != null) {
                OAuthApi account = accounts.get(cuentaActual);
                LOGGER.log(Level.INFO, "Reuso de cuenta ({0}/{1}) status = {2} detalle = {3} nueva cuenta:{4}" + status.getErrorMessage(), new Object[]{account.getLimitStatus().getRemaining(), account.getLimitStatus().getLimit(), status.getStatusCode(), status.getErrorMessage(), accounts.get(cuentaActual).getScreenName()});
            } else {
                RateLimitStatus limitStatus = accounts.get(cuentaActual).getLimitStatus();
                if (limitStatus != null) {
                    LOGGER.log(Level.INFO, "Reuso de cuenta ({0}/{1}) status = {2} detalle = {3} nueva cuenta:{4}", new Object[]{limitStatus.getRemaining(), limitStatus.getLimit(), null, null, accounts.get(cuentaActual).getScreenName()});
                } else {
                    LOGGER.log(Level.INFO, "Reuso cuenta, sin informacion estado");
                }
            }
        }
        return twitter;
    }

    private void updateTwitter(TwitterResponse response) {
        OAuthApi account = accounts.get(cuentaActual);

        account.setLimitStatus(response.getRateLimitStatus());
    }

    /**
     * Verifica se encuentre correctamente configurada la sesion de twitter caso
     * contrario, la configura.
     */
    @Override
    public RequestToken getRequestToken() {
        try {
            twitter = new TwitterFactory().getInstance();
            twitter.setOAuthConsumer(consumerKey, consumerSecret);
            RequestToken requestToken = twitter.getOAuthRequestToken();
            return requestToken;
        } catch (twitter4j.TwitterException ex) {
            Logger.getLogger(TwitterClientImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    @Override
    public void addTwitter(RequestToken requestToken, String pin) {
        AccessToken accessToken = null;
        if (pin != null) {
            try {
                if (pin.length() > 0) {
                    accessToken = getTwitter(null).getOAuthAccessToken(requestToken, pin);
                    if (accessToken != null) {
                        //persist to the accessToken for future reference.
                        System.out.println(twitter.verifyCredentials().getId());
                        OAuthApi auth = new OAuthApi();
                        auth.setId(twitter.verifyCredentials().getId());
                        auth.setScreenName(twitter.verifyCredentials().getScreenName());
                        auth.setToken(accessToken.getToken());
                        auth.setTokenSecret(accessToken.getTokenSecret());
                        System.out.println("token : " + accessToken.getToken());
                        System.out.println("tokenSecret : " + accessToken.getTokenSecret());
                        accounts.add(auth);
                        configDao.update(auth);
                    }
                }
            } catch (twitter4j.TwitterException te) {
                if (STATUS_INVALID_TOKEN == te.getStatusCode()) {
                    System.out.println("Unable to get the access token.");
                } else {
                    te.printStackTrace();
                }
            }
        }

    }
}
